package org.example.framework;

import org.example.Application;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

public class MyApp {
    private static String Classkey="bootstrapClass";

    //读取属性文件
    public static Properties LoadProperties(String prop_file) throws MyException{
        Properties props=new Properties();
        //读取配置文件
        try(InputStream input= Application.class.getResourceAsStream(prop_file))
        {
         if(input==null){
             throw new MyException(MyException.ErrorType.FILE_NOTFOUND,"未找到配置文件");
         }
        props.load(input);
         return props;
        }
        catch(IOException e){
            throw new MyException(MyException.ErrorType.PROP_READ_ERROR,"配置文件读取失败");
        }

    }

    //根据属性获取类
    public static Class getClass(Properties properties)throws MyException{
        String classname= properties.getProperty(Classkey);
        if(classname==null){
            throw new MyException(MyException.ErrorType.PROP_NOTFOUND,"未找到bootstrapClass属性信息");
        }
        try{
        Class cls=Class.forName(classname);
        return cls;
        }
        catch(ClassNotFoundException e){
            throw new MyException(MyException.ErrorType.CLASS_NOTFOUND,"未找到属性中标明的类");
        }
    }

    //创建类的对象
    public static Object creatObject(Class clazz) throws MyException {
        try {
            return clazz.newInstance();
        } catch (InstantiationException e) {
            throw new MyException(MyException.ErrorType.CREATE_OBJECT_ERROR, "创建对象失败：请检查是否有无参构造函数");
        } catch (IllegalAccessException e) {
            throw new MyException(MyException.ErrorType.CREATE_OBJECT_ERROR, "创建对象失败：类不能是抽象类，无参构造函数不能为私有");
        }
    }

    //获取类中有自定义注解的方法
    public static Method getInitMethod(Class clazz)throws MyException{
        Method[] methods=clazz.getDeclaredMethods();
        for(Method mt:methods){
            if(!mt.isAnnotationPresent(InitMethod.class)){
                continue;
            }
            if(mt.getParameterCount()>0){
                throw new MyException(MyException.ErrorType.INITMETHOD_ERROR,"标注@InitMethod的方法不能带参数");
            }
            return mt;
        }
        throw new MyException(MyException.ErrorType.INITMETHOD_ERROR,"类中无@InitMethod的方法");
    }

    //对象调用方法
    public static void invokeMethod(Object obj, Method method) throws MyException {
        try {
            method.setAccessible(true);
            method.invoke(obj);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new MyException(MyException.ErrorType.METHOD_CALL_ERROR, "调用方法失败：请检查方法是否是私有或者抽象的");
        }
    }

}
